<?php

/*

	Copyright © 2011 Mike Bennett <mike@kereru.com>

	This file is part of Tazu-Time.

    Tazu-Time is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    Tazu-Time is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Tazu-Time.  If not, see <http://www.gnu.org/licenses/>.
    
*/


/**
*	Platform specific code and routines
*	
*	@param	
*	@return	
*	
*/

if(!defined('OS_WIN32')) define("OS_WIN32",	1);
if(!defined('OS_GTK2')) define("OS_GTK2",	2);
if(!defined('OS_IN_USE')) define("OS_IN_USE", OS_WIN32);

class win32 {


	/**
	*	Path to user application data folder.
	*	
	*	@param	
	*	@return	string path (no trailing slash)
	*	
	*/
  	static static function app_data($folder='RocketDMS') {
		$os = platform::os_ver();

		// Kludge - b3rtWindowsRegistry does not seem to get the correct expanded strings
		$strMainKey= "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
		$value = 'AppData';
		
		$mainKey= reg_open_key( HKEY_CURRENT_USER, $strMainKey );
		$home = reg_get_value($mainKey,$value);
		reg_close_key($mainKey);		
		$home = str_replace('%USERPROFILE%',getenv('USERPROFILE'),$home);

		if ( $home == '' ) getenv('APPDATA');

		$home .= "\\".$folder."\\";
		
		if ( ! is_dir( $home ) ) @mkdir($home,0777,TRUE);
		
		return($home);
	
	}
	

	static function browse_folder($path=FALSE,$caption='Select Folder') {
		$path = platform::path($path);
//echo "[$path]";
		
		$selected_folder= win_browse_folder($path, $caption);
		return($selected_folder);
	}

	/**
	*	Shell a command  (non modal)
	*	
	*	@param	
	*	@return	
	*	
	*/
	static function exec($cmd,$param='',$minimised=TRUE,$wait=FALSE,$run=FALSE) {

		if ( (substr($cmd,0,4) == 'http') || (substr(strrev($cmd),0,4) == 'lmth') || (substr(strrev($cmd),0,3) == 'mth') ) {
			// URL launch
			try {
				$shell = new COM("WScript.Shell");
				$shell -> Run("\"$cmd\"".' '.$param,$minimised?2:1 , $wait );
//$shell -> Run($cmd.' '.$param,$minimised?2:1 , 0 );
			} catch (Exception $e) {
//			    echo 'Caught exception: ',  $e->getMessage(), "\n";
			    trigger_error('platform::exec url launch Caught exception: '.$e->getMessage());
			}

		}
		else {
			// Executable
			$cmd = platform::path($cmd);
			$path_parts = pathinfo($cmd);
			
			// could be called as, say, core.exe, want to run as core.php if debugging
			$php = $path_parts['filename'].'.php';

			// could be called as, say, rdms_core.exe, want to run as core.php if debugging
			if ( substr($path_parts['filename'],0,5) == 'rdms_') {
				$php = substr($path_parts['filename'],5).'.php';
			}
						
			if ( file_exists($php)) {
				// interpreted - testing		
//				$cmd = "C:\\PHP-Gtk2\\php-win.exe";
				$cmd = "C:\\PHP-Gtk2\\php.exe";
				$param = sprintf("%s %s",$php,$param);
			}

//			if ( file_exists($cmd) ) {
				try {
					$shell = new COM("WScript.Shell");
//					if ( $run ) {
						$result = $shell -> Run("\"$cmd\"".' '.$param,$minimised?2:1 , $wait );
//					}
//					else {
//						$result = $shell -> Exec("\"$cmd\"".' '.$param);
						
//echo $result->ExitCode."\n";
//echo $result->StdErr."\n";
//echo $result->StdOut."\n";
//echo $cmd.' '.$param."\n";

//					}
				} catch (Exception $e) {
				    trigger_error('platform::exec executable launch Caught exception: '.$e->getMessage());
					platform::error_popup('Unable to exec : '.$cmd.' '.$param.'  '.$e->getMessage());
				}
//			}
//			else {
//				platform::error_popup('Unable to exec : '.$cmd.' '.$param);
//			}
		}
	}


	static function file_save($path,$filename,$filter=FALSE,$caption='File Save') {
		$selected_file= win_browse_file(false, $path, $filename, null, $filter);
		return($selected_file);
	}

	static function file_select($path,$filename,$filter=FALSE,$caption='File Open') {
		$selected_file= win_browse_file(true, $path, $filename, null, $filter);
		return($selected_file);
	}

	static function find_file($exe) {

		$filepath = sprintf("%s\\%s",getenv('windir'),$exe);
		if ( file_exists( $filepath )) return($filepath);

		$filepath = sprintf("%s\\%s",getenv('SystemRoot'),$exe);
		if ( file_exists( $filepath )) return($filepath);

		return($exe);
	}

	static function icon($ext) {
		// Attempt to find icon from registry
//		HKEY_CLASSES_ROOT\.rdb

		$windowsRegistry = new b3rtWindowsRegistry();
		$key = $windowsRegistry->ReadValue('HKEY_CLASSES_ROOT\\.'.$ext, '', TRUE);

		$icon = $windowsRegistry->ReadValue('HKEY_CLASSES_ROOT\\'.$key.'\\DefaultIcon', '', TRUE);
// INCOMPLETE		

//echo 'HKEY_CLASSES_ROOT\\'.$key.'\\DefaultIcon'."\n";
//echo "[[$icon]]";

	}


	static function temp($use_ramdisk=TRUE) {

		if ( $GLOBALS['ramdisk'] <> '' && $use_ramdisk ) {
			$tmp = $GLOBALS['ramdisk'].'tmp\\';
			if ( ! is_dir($tmp) ) {
				// Some problem with the rmadisk - revert to st temp
				$tmp = getenv('TEMP').'\\';
				if ( getenv('TEMP') == '' ) {
					$tmp = "C:\\Temp\\";  //DevPHP
					@mkdir($tmp);
				}
			}
		}
		else {
			$tmp = getenv('TEMP').'\\';
			if ( getenv('TEMP') == '' ) {
				$tmp = "C:\\Temp\\";  //DevPHP
				@mkdir($tmp);
			}
			
		
		}

		
 // Problem with checking every time. Make it check only on program startup.
 
		
		// It is critical that we can write to the TEMP folder
//		@file_put_contents($tmp.'tmp_test','test_write_temp');
//		$result = @file_get_contents($tmp.'tmp_test');
//		if ( $result <> 'test_write_temp' ) {
//			trigger_error('FATAL ERROR : Unable to write to TEMP : '.$tmp,E_USER_ERROR);
//		}
//		@unlink($tmp.'tmp_test');

		
		
		return($tmp);
	}

	
	/*
	Return current user home path
	*/
	static function home() {
		$home = getenv('USERPROFILE');
		return($home);
	}
	

	/*
	Return current user mydocs path
	*/
	static function my_documents() {
#*todo*	
		
		$os = platform::os_ver();

		
		// Kludge - b3rtWindowsRegistry dies not seem to get the correct expanded strings
		$strMainKey= "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
		$value = 'Personal';
		
		$mainKey= reg_open_key( HKEY_CURRENT_USER, $strMainKey );
		$home = reg_get_value($mainKey,$value);
		reg_close_key($mainKey);		
		$home = str_replace('%USERPROFILE%',getenv('USERPROFILE'),$home);

		if ( $home == '' ) {
			if ( $os >= 6 ) {
				// vista, win7
				$home = getenv('USERPROFILE')."\\Documents";
			}
			else {
				$home = getenv('USERPROFILE')."\\My Documents";
			}	
		}
		
		return($home);
	
	}
	


}

class gtk2 {

	static function app_data() {
	
		return("./");
	
	}


	static function browse_folder($path=FALSE,$caption='Select Folder') {


		$dialog = new GtkFileChooserDialog(
											$caption, 
											null, 
											Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER,
											array(Gtk::STOCK_OK, Gtk::RESPONSE_OK), 
											null
										);


//	    $dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
	    $dialog->set_position(Gtk::WIN_POS_MOUSE);

		$dialog->set_title($caption);
		$dialog->set_icon_from_file(PATH_RES.'app_icon_16.png');
		if ( $path ) $dialog->set_current_folder($path);
		$dialog->show_all();

		$selected_folder = FALSE;
		if ($dialog->run() == Gtk::RESPONSE_OK) {
			$selected_folder = $dialog->get_filename(); 
		}

		$dialog->destroy();

		return($selected_folder);

	
	}


	/**
	*	Shell a command  (non modal)
	*	
	*	@param	
	*	@return	
	*	
	*/
	static function exec($cmd,$param='',$minimised=TRUE) {
		exec($cmd.' '.$param);
	}


	static function file_save($path,$filename,$filter=FALSE,$caption='File Save') {
		$filename = new file_saveas($path,$filename,$filter,$caption);
		$selected_file = $filename->get();
		return($selected_file);
	}

	static function file_select($path,$filename,$filter=FALSE,$caption='File Open') {
		$filename = new file_chooser($path,$filename,$filter,$caption);
		$selected_file = $filename->get();
		return($selected_file);
	}

	static function find_file($exe) {
		return($exe);
	}

	static function icon($ext) {
		return(FALSE);
	}

	static function temp() {
		return("\\tmp\\");	
	}

	
	/*
	Return current user home path
	*/
	static function home() {
		return("./");
	}
	

	/*
	Return current user mydocs path
	*/
	static function my_documents() {
		return("./");
	}
	
}

class platform {



	/**
	*	Place txt into clipboard
	*	
	*	@param	
	*	@return	
	*	
	*/
	static function clipboard($txt) {

		$tmpfile = platform::path(platform::temp().'clipboard.txt');

		// Pipe text into clipboard
		@file_put_contents($tmpfile,$txt);

		$cmd = sprintf("utils\cb.bat");
		$param = sprintf("\"%s\"",$tmpfile);

		platform::exec($cmd,$param);

//echo "[$cmd $param]";


	}

	/**
	*	Path to icon for given extension.
	*	
	*	@param	
	*	@return	string path (no trailing slash)
	*	
	*/
	static function icon($ext) {
		if ( OS_IN_USE == OS_WIN32 ) {
			return( platform::path_r(win32::icon($ext)) );
		}
		else {
			return( platform::path_r(gtk2::icon($ext)) );
		}
	}
	


	/**
	*	Path to user application data folder.
	*	
	*	@param	
	*	@return	string path (no trailing slash)
	*	
	*/
	static function app_data($folder='RocketDMS') {
		if ( OS_IN_USE == OS_WIN32 ) {
			return( platform::path_r(win32::app_data($folder)) );
		}
		else {
			return( platform::path_r(gtk2::app_data($folder)) );
		}
	}
	


	/**
	*	Return path to temp folder
	*	
	*	@param	
	*	@return	
	*	
	*/
	static function temp($use_ramdisk=TRUE) {
		if ( OS_IN_USE == OS_WIN32 ) {
			return( platform::path_r(win32::temp($use_ramdisk)) );
		}
		else {
			return( platform::path_r(gtk2::temp($use_ramdisk)) );
		}
	}
	

	static function home() {
		if ( OS_IN_USE == OS_WIN32 ) {
			return( platform::path_r(win32::home()) );
		}
		else {
			return( platform::path_r(gtk2::home()) );
		}
	}
	
	static function my_documents() {
		if ( OS_IN_USE == OS_WIN32 ) {
			return( platform::path_r(win32::my_documents()) );
		}
		else {
			return( platform::path_r(gtk2::my_documents()) );
		}
	}
	


	static function find_file($exe) {

		
		if ( OS_IN_USE == OS_WIN32 ) {
			return( platform::path_r(win32::find_file($exe)) );
		}
		else {
			return( platform::path_r(gtk2::find_file($exe)) );
		}

	
	}


	static function browse_folder($path=FALSE,$caption='Select Folder') {

		if ( WIN_DIALOG ) {
			return( platform::path_r(win32::browse_folder($path,$caption)) );
		}
		else {
			return( platform::path_r(gtk2::browse_folder($path,$caption)) );
		}

	
	}

	static function exec($c,$p='',$minimised=FALSE,$wait=FALSE,$run=TRUE) {

		if ( OS_IN_USE == OS_WIN32 ) {
			return( win32::exec($c,$p,$minimised,$wait,$run) );
		}
		else {
			return( gtk2::exec($c,$p,$minimised,$wait,$run) );
		}

	
	}

	static function file_save($path,$filename,$filter=FALSE,$caption='File Save') {

		if ( WIN_DIALOG ) {
			return( platform::path_r(win32::file_save($path,$filename,$filter,$caption)) );
		}
		else {
			return( platform::path_r(gtk2::file_save($path,$filename,$filter,$caption)) );
		}

	}

	static function file_select($path,$filename,$filter=FALSE,$caption='File Open') {

		if ( WIN_DIALOG ) {
			return( platform::path_r(win32::file_select($path,$filename,$filter,$caption)) );
		}
		else {
			return( platform::path_r(gtk2::file_select($path,$filename,$filter,$caption)) );
		}

	}


	static function yes_no($msg,$caption='Please Confirm') {

/*
Value
	
Symbolic name
	
Description
  0	Gtk::WIN_POS_NONE	No influence is made on placement.
  1	Gtk::WIN_POS_CENTER	Windows should be placed in the center of the screen.
  2	Gtk::WIN_POS_MOUSE	Windows should be placed at the current mouse position.
  3	Gtk::WIN_POS_CENTER_ALWAYS	Keep window centered as it changes size, etc.
  4	Gtk::WIN_POS_CENTER_ON_PARENT	Center the window on its transient parent (see set_transient_for() ). 
 
 */

		$dialog = new GtkMessageDialog (
							$parent_win,
							Gtk::DIALOG_MODAL,
							Gtk::MESSAGE_QUESTION,
							Gtk::BUTTONS_YES_NO,
							$msg
							);		

//	    $dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
//	    $dialog->set_position(Gtk::WIN_POS_CENTER);
	    $dialog->set_position(Gtk::WIN_POS_MOUSE);


		$dialog->set_title($caption);
		$dialog->set_markup("<b>$caption</b>\n\n$msg");
		$dialog->set_icon_from_file(PATH_RES.'app_icon_16.png');

		$answer = $dialog->run();

		$dialog->destroy();

		return( $answer == Gtk::RESPONSE_YES );

	}


	/**
	*	return array of file filter terms for file select popups
	*	
	*	@param	
	*	@return	
	*	
	*/
	static function file_filter() {

	    $file_filter = array(
	        "All files" =>          "*.*",
	        "Word Documents" => 	   	"*.doc",
	        "OpenOffice Document"=>"*.odt",
	        "OpenOffice Spreadsheet"=>"*.odt",
	        "Excel Spreadsheet"=>	"*.xls",
	        "Email"=>				"*.eml",
	        "PDF Document"=>		"*.pdf",
	        "Web Pages"=>           "*.htm?",
	        "Text Document"=>      "*.txt",
	    );


		return( $file_filter );
	
	}

	// display popup alert box - note 2
	static function auth_popup($msg) {
	
	    $dialog = new GtkDialog('Alert', null, Gtk::DIALOG_MODAL);
		$dialog->set_icon_from_file(PATH_RES . 'dms.ico' );

//	    $dialog->set_position(Gtk::WIN_POS_CENTER_ALWAYS);
//	    $dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
//	    $dialog->set_position(Gtk::WIN_POS_CENTER);
	    $dialog->set_position(Gtk::WIN_POS_MOUSE);

	    $top_area = $dialog->vbox;
	    $top_area->pack_start($hbox = new GtkHBox());
	    $stock = GtkImage::new_from_stock(Gtk::STOCK_DIALOG_WARNING,
	        Gtk::ICON_SIZE_DIALOG);
	    $hbox->pack_start($stock, 0, 0);
	    $hbox->pack_start(new GtkLabel($msg));
	    $dialog->add_button(Gtk::STOCK_OK, Gtk::RESPONSE_OK);
	    $dialog->set_has_separator(false);
	    $dialog->show_all();
	    $dialog->run();
	    $dialog->destroy();
	} 



	static function error_popup($msg,$caption='RocketDMS - Oops!') {
		if ( $msg == '' ) return;

		if ( is_object('log')) {
			log::error('Error popup:'.str_replace("\n",' ',$msg));
		}
				
		$dialog = new GtkMessageDialog (
							$parent_win,
							Gtk::DIALOG_MODAL,
							Gtk::MESSAGE_ERROR,
							Gtk::BUTTONS_OK,
							$msg
							);		

//	    $dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
//	    $dialog->set_position(Gtk::WIN_POS_CENTER);
	    $dialog->set_position(Gtk::WIN_POS_MOUSE);

		$dialog->set_title($caption);
		$dialog->set_markup("<b>$caption</b>\n\n$msg");
		$dialog->set_icon_from_file(PATH_RES.'app_icon_16.png');

		$answer = $dialog->run();
		$dialog->destroy();
	}

	static function message($msg,$caption='RocketDMS') {
		platform::message_popup($msg,$caption);
	}

	static function message_popup($msg,$caption='RocketDMS') {
		if ( $msg == '' ) return;
		
		if ( is_object('log')) {
			log::error('Message popup:'.str_replace("\n",' ',$msg));
		}
		
		$dialog = new GtkMessageDialog (
							$parent_win,
							Gtk::DIALOG_MODAL,
							Gtk::MESSAGE_INFO,
							Gtk::BUTTONS_OK,
							$msg
							);		

//	    $dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
//	    $dialog->set_position(Gtk::WIN_POS_CENTER);
	    $dialog->set_position(Gtk::WIN_POS_MOUSE);

		$dialog->set_title($caption);
		$dialog->set_markup("<b>$caption</b>\n\n$msg");
		$dialog->set_icon_from_file(PATH_RES.'app_icon_16.png');

		$answer = $dialog->run();
		$dialog->destroy();
	}



	// fixme
	static function is_windows() {
		return(TRUE);	
	}
	
	
	static function is_dir($dir) {
		$dir = platform::path($dir);
		return( is_dir($dir));	
	}



	/**
	*	Get the operating system
	*	
	*	@param	
	*	@return	string OS 
	*	
	*/
	static function os() {
		$windowsRegistry = new b3rtWindowsRegistry();
		$val = $windowsRegistry->ReadValue('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion','ProductName', TRUE);
		return( $val );
	}
	
	/**
	*	Get the operating system version
	*	
	*	@param	
	*	@return	string OS version
	*	
	*/
	static function os_ver() {
		$windowsRegistry = new b3rtWindowsRegistry();
		$val = $windowsRegistry->ReadValue('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion','CurrentVersion', TRUE);

/*
		$product = strtolower($windowsRegistry->ReadValue('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion','ProductName', TRUE));
		if ( substr($product,0,9) == 'windows 7') {
			// My laptop windows 7 pro returns os version 6.1
		}
*/		
		return( $val );
	}


	/**
	*	Convert paths for os
	*	
	*	@param	
	*	@return	string Path with either forward or back slashes
	*	
	*/
	static function path($p) {

		if ( platform::is_windows() ) {
			$p = str_replace("/","\\",$p);
		}
		else {
			$p = str_replace("\\","/",$p);
		}

		return($p);
	}
	
	/**
	*	Convert paths for internal rocketdms use
	*	
	*	@param	
	*	@return	string Path with either forward or back slashes
	*	
	*/
	static function path_r($p) {
		$p = str_replace("\\","/",$p);
		return($p);
	}
	

	/**
	*	Initialise ramdisk if in use
	*	
	*	@param	
	*	@return	
	*	
	*/
	static function ramdisk(&$cnf) {

		$rd = $cnf->ini['ROCKET']['ramdisk'];
		if ($rd == '-') $rd='';
		if ($rd == '0') $rd='';
		
		$GLOBALS['ramdisk'] = '';
		if ( $rd <> '' ) {

			$r = platform::path($rd);
			$GLOBALS['ramdisk'] = $r;

			$svn = platform::path($cnf->ini['SUBVERSION']['bin']);
			
			if ( ! is_dir($r.$svn) ) @mkdir($r.$svn,0777,TRUE);
			if ( ! is_dir($r.'tmp') ) @mkdir($r.'tmp',0777,TRUE);

			if ($handle = opendir($svn)) {
			    while (false !== ($file = readdir($handle))) {
			        if ($file != "." && $file != ".." && $file != '.svn') {
			        	if ( file_exists( platform::path($svn.'/'.$file) ) ) {
							@copy(platform::path($svn.'/'.$file),platform::path($r.$svn.'/'.$file));
						}
			        }
			    }
			    closedir($handle);
			}
		}

	}

    /**
    *   converts a file path gotten from a text/uri-list
    *   drop to a usable local filepath
    *   @param  string  The line from the uri-list
    *   @return string  The usable local filepath
    */
	// see: http://gtk.php.net/manual1/en/tutorials.filednd.finalprog.php
    static function getPathFromUrilistEntry($strUriFile)
    {
        $strUriFile = urldecode($strUriFile);//should be URL-encoded
        $bUrl = false;
        if (substr($strUriFile, 0, 5) == 'file:')
        {   //(maybe buggy) file protocol
            if (substr($strUriFile, 0, 17) == 'file://localhost/') {
                //correct implementation
                $strFile = substr($strUriFile, 16);
            } else if (substr($strUriFile, 0, 8) == 'file:///') {
                //no hostname, but three slashes - nearly correct
                $strFile = substr($strUriFile, 7);
            } else if ($strUriFile[5] == '/') {
                //theoretically, the hostname should be the first
                //but no one implements it
                $strUriFile = substr($strUriFile, 5);
                for( $n = 1; $n < 5; $n++) {
                    if ($strUriFile[$n] != '/') { break; }
                }
                $strUriFile = substr($strUriFile, $n - 1);
                if (!file_exists($strUriFile)) {
                    //perhaps a correct implementation with hostname???
                    $strUriFileNoHost = strstr(substr($strUriFile, 1), '/');
                    if (file_exists($strUriFileNoHost)) {
                        //seems so
                        $strUriFile = $strUriFileNoHost;
                    }
                }
                $strFile = $strUriFile;
            } else {
                //NO slash after "file:" - what is that for a crappy program?
                $strFile = substr ($strUriFile, 5);
            }
        }
        elseif (substr($strUriFile, 0, 5) == 'rdms:')
        {   
                $strFile = substr($strUriFile, 7);
        } else if (strstr($strUriFile, '://')) {
            //real protocol, but not file
            $strFile = $strUriFile;
            $bUrl    = true;
        } else {
            //local file?
            $strFile = $strUriFile;
        }
        if (!$bUrl && $strFile[2] == ':' && $strFile[0] == '/') {
            //windows file path
            $strFile = str_replace('/', '\\', substr($strFile, 1));
        }
        return $strFile;
    }

}


?>